/*
 * @Description: 生产环境
 * @Author: wangqi
 * @Date: 2021-03-02 20:47:11
 * @LastEditTime: 2021-03-17 17:40:38
 */
const path = require('path')
const { merge } = require('webpack-merge')
const common = require('./webpack.common')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
// 分离出css文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 压缩css
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
// 多线程打包
const HappyPack = require('happypack');
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

console.log(process.env.NODE_ENV, "生产模式")

module.exports = merge(common, {
    // development || production
    mode: "production",
    target: 'browserslist',
    devtool: 'cheap-module-source-map',
    output: {
        publicPath: "./",
    },
    module: {
        rules: [
            {
                oneOf: [
                    {
                        test: /\.(js|jsx)$/,
                        use: [{
                            loader: 'babel-loader',
                            options: {
                                // options、query不能和loader数组一起使用
                                // presets: ['@babel/preset-env'],
                                presets: [['@babel/preset-env', {
                                    useBuiltIns: 'usage',
                                    corejs: {
                                        version: 3
                                    },
                                }]],
                                // 开启babel缓存，提高性能; (未变化的不用重新加载)
                                cacheDirectory: true
                            },
                        }],
                        exclude: /node_modules/,
                        include: path.resolve(__dirname, 'src'),
                    },
                    {
                        test: /\.css$/,
                        use: [
                            { loader: MiniCssExtractPlugin.loader, options: { publicPath: '../' } },
                            'css-loader',
                            {
                                loader: 'postcss-loader',
                                // options: {
                                //     ident: 'postcss',
                                //     plugins: () => [require('postcss-preset-env')()]
                                // }
                            }
                        ],
                        // 不检测的文件
                        exclude: /node_modules/,
                        // 指定检查的目录
                        include: path.resolve(__dirname, 'src'),
                    },
                    {
                        test: /\.(less)$/i,
                        use: [
                            { loader: MiniCssExtractPlugin.loader, options: { publicPath: '../' } },
                            'css-loader',
                            'less-loader',
                            {
                                loader: 'postcss-loader',
                                // options: {
                                //     ident: 'postcss',
                                //     plugins: () => [require('postcss-preset-env')()]
                                // }
                            }
                        ],
                        // 不检测的文件
                        exclude: /node_modules/,
                        include: path.resolve(__dirname, 'src'),
                    }
                ]
            },

        ]
    },
    plugins: [
        new CleanWebpackPlugin(),
        new MiniCssExtractPlugin({
            filename: 'css/[name].[chunkhash:6].css',
            chunkFilename: 'css/wqhash-[name].[contenthash:4].css',
        }),
        new HappyPack({
            id: 'js',
            //如何处理  用法和loader 的配置一样
            loaders: ['babel-loader'],
            //共享进程池
            threadPool: happyThreadPool,
            //允许 HappyPack 输出日志
            verbose: true,
        }),
    ],
    optimization: {
        // 打包文件keys的名称 [默认自增id]
        // moduleIds: 'named',
        // 模块只导出被使用的成员 [three shaking]
        usedExports: true,
        runtimeChunk: {
            // name: "manifest",
            name: entrypoint => `runtime-${entrypoint.name}`
        },
        // 合并模块
        concatenateModules: true,
        minimizer: [
            // js压缩可配置
            new UglifyJsPlugin({
                cache: true,
                parallel: true,
                // set to true if you want JS source maps
                sourceMap: false,
            }),
            // css压缩可配置
            new OptimizeCssAssetsWebpackPlugin({})
        ],
        splitChunks: {
            chunks: "all",                      //async异步代码分割 initial同步代码分割 all同步异步分割都开启
            minSize: 30000,                     //字节 引入的文件大于30kb才进行分割
            //maxSize: 50000,                   //50kb，尝试将大于50kb的文件拆分成n个50kb的文件
            minChunks: 2,                       //模块至少使用次数
            maxAsyncRequests: 5,                //同时加载的模块数量最多是5个，只分割出同时引入的前5个文件
            maxInitialRequests: 3,              //首页加载的时候引入的文件最多3个
            automaticNameDelimiter: '~',        //缓存组和生成文件名称之间的连接符
            // name: true,                      //缓存组里面的filename生效，覆盖默认命名
            cacheGroups: {
                lib: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'lib',
                    chunks: 'initial',
                    minChunks: 1,
                    // 定义打包组的打包顺序优先级，值越大，优先级越高
                    priority: 3,
                    //模块嵌套引入时，判断是否复用已经被打包的模块
                    reuseExistingChunk: true,
                },
                polyfill: {
                    test: /[\\/]node_modules[\\/](core-js|@babel|regenerator-runtime)/,
                    name: 'polyfill',
                    priority: 70,
                    minChunks: 1,
                    reuseExistingChunk: true
                },
                styles: {
                    name: 'styles',
                    test: /\.(scss|less|css)$/,
                    chunks: 'all',
                    minChunks: 1,
                    reuseExistingChunk: true,
                    enforce: true
                }
            },
        },

    },
    // 拒绝外部文件被打包进来
    externals: {
        jquery: 'jQuery'
    }
})